package com.koomii.common.springmvc.interceptor;

import com.koomii.common.util.JsonUtil;
import com.koomii.common.web.LoginContext;
import com.koomii.common.web.MenuContext;
import com.koomii.common.web.VendorLoginContext;
import com.koomii.common.web.cookie.CookieUtils;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
 *
 * port from .NewLoginContextInterceptor
 *
 * @see //.NewLoginContextInterceptor
 * @see //LoginContextInterceptor
 * @author
 *
 */
public class VendorLoginContextInterceptor extends HandlerInterceptorAdapter {

    private final static Log log = LogFactory
            .getLog(VendorLoginContextInterceptor.class);
    protected CookieUtils cookieUtils;

    protected String loginCookieKey = "hi_dxh";
    protected String menuCookieKey = "menu_dxh";
    /**
     * 判断session有效时间，单位：秒 1800 为 30 * 60 。30分钟
     */
    protected int sessionTimeout = 1800;
    /**
     * 写入cookie的时机
     */
    protected int rate = 2;

    /**
     *
     * @param cookieValue
     * @return
     */
    protected VendorLoginContext getVendorLoginContext(String cookieValue) {
        return VendorLoginContext.parse(cookieValue);
    }

    public void setCookieUtils(CookieUtils cookieUtils) {
        this.cookieUtils = cookieUtils;
    }

    /**
     *
     * @param loginCookieKey
     */
    public void setLoginCookieKey(String loginCookieKey) {
        this.loginCookieKey = loginCookieKey;
    }

    public void setSessionTimeout(int sessionTimeout) {
        this.sessionTimeout = sessionTimeout;
    }

    public void setRate(int rate) {
        this.rate = rate;
    }

    @Override
    public final boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler)
            throws ServletException,
            IOException {
        try {
            updateLogin(request, response);
            updateMenuContext(request,response);
        } catch (Exception e) {
            log.warn("updatelogin error!", e);
        }

        return true;
    }

    private void updateMenuContext(HttpServletRequest request, HttpServletResponse response) {
        if(menuCookieKey!=null){
            String mCode = request.getParameter("navId");
            //字符为 一级菜单编码-二级菜单编码
            String mCode3 = request.getParameter("sNavId");
            String value = cookieUtils.getCookieValue(request,menuCookieKey);
            if(StringUtils.isNotEmpty(value)){
                MenuContext mc = JsonUtil.g.fromJson(value,MenuContext.class);
                if(StringUtils.isNotEmpty(mCode)){
                    log.info("choose first menu "+mCode);
                    mc.setOne(mCode);
                    //通过一级菜单点击时   二三级菜单选中取消
                    mc.setTwo("");
                    mc.setThree("");
                }else{
                    if(StringUtils.isNotEmpty(mCode3)){
                        String[] strs = mCode3.split("-");
                        if(strs!=null && strs.length==2 ){
                            log.info("choose second menu "+strs[0]);
                            mc.setTwo(strs[0]);
                            log.info("choose third menu "+strs[1]);
                            mc.setThree(strs[1]);
                        }
                    }
                }
                MenuContext.setMenuContext(mc);
                cookieUtils.setCookie(response,menuCookieKey,JsonUtil.g.toJson(mc));
            }
        }
    }

    public void postHandle(
            HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception {
        if(modelAndView!=null){
            //处理请求中的值
            VendorLoginContext context = VendorLoginContext.getVendorLoginContext();
            if(context!=null && context.isLogin()){
                log.info("login success .user pin="+context.getPin());
                modelAndView.addObject("loginContext",context);
            }
            //获取menuContext
            MenuContext menuContext = MenuContext.getMenuContext();
            if(menuContext!=null){
                modelAndView.addObject("mContext",menuContext);
            }
        }
    }

    public void afterCompletion(
            HttpServletRequest request, HttpServletResponse response,
            Object handler, Exception ex)
            throws Exception {
        VendorLoginContext.remove();
    }

    protected void updateLogin(HttpServletRequest request,
            HttpServletResponse response) {
        // 判断是否配置了cookie的cookie名称
        if (loginCookieKey != null) {
            try {
                String value = cookieUtils.getCookieValue(request,loginCookieKey);
                if (StringUtils.isNotBlank(value)) {// 能取到值
                    VendorLoginContext context = getVendorLoginContext(value);
                    if (context != null) {// 又能解出来
                        long current = System.currentTimeMillis();
                        long created = context.getCreated();
                        long expires = context.getExpires();
                        long timeout = expires == 0 ? sessionTimeout * 1000
                                : expires - created;// 如果没有设置过期时间，则使用默认的
                        if (current - created < timeout) { // 如果没有过期
                            VendorLoginContext.setVendorLoginContext(context);
                            if ((current - created) * rate > timeout) {// 如果剩下的时间只有2/3，就需要重新派发cookie
                                log.info("session cookie[" + loginCookieKey + "] rewrite!");
                                // 写最后一次访问的cookie
                                context.setCreated(current);
                                if (expires != 0) {
                                    context.setTimeout(timeout);
                                }
                                cookieUtils.setCookie(response, loginCookieKey,context.toCookieValue());
                            }
                        } else {
                            log.info("session cookie[" + loginCookieKey+ "] is valid!");
                            // 超时后，要清空
                            cookieUtils.invalidate(request, response);
                        }
                    } else {
                        log.info("session cookie[" + loginCookieKey + "] is error!");
                    }
                } else {
                    log.info("session cookie[" + loginCookieKey + "] is empty!");
                }
            } catch (Exception e) {
                log.error("login intercept error", e);
            }
        } else {
            log.debug("session cookie key is empty!");
        }

    }

    public void setMenuCookieKey(String menuCookieKey) {
        this.menuCookieKey = menuCookieKey;
    }
}
